<!DOCTYPE html>
<html>
    <head>
        <script src="/w3c/resources/testharness.js"></script>
        <script src="/w3c/resources/testharnessreport.js"></script>
        <script src="mediasource-util.js"></script>
    </head>
    <body>
        <div id="log"></div>
        <script>
          mediasource_testafterdataloaded(function(test, mediaElement, mediaSource, segmentInfo, sourceBuffer, mediaData)
          {
              // Set duration .5 nanoseconds higher than known duration. Internally, most user
              // agents do not represent media time with sub-nanosecond precision, so this attempts
              // to catch edge cases arising from data type conversions.
              let increased_duration = segmentInfo.duration + /* .5 nanoseconds */ .0000000005;
              mediaSource.duration = increased_duration;

              // Expect duration to exactly match what was set.
              assert_equals(mediaSource.duration, increased_duration);

              // Append media data.
              test.expectEvent(sourceBuffer, "updateend");
              sourceBuffer.appendBuffer(mediaData);
              test.waitForExpectedEvents(function()
              {
                  // Appending all data should not change the duration because set duration is
                  // already larger than segmentInfo metadata (and we trust segmentInfo has an
                  // accurate duration - see mediasource-duration.html).
                  assert_equals(mediaSource.duration, increased_duration);

                  // Marking end of stream should cause duration to be reduced to match highest
                  // buffered end time.
                  mediaSource.endOfStream();

                  assert_equals(mediaElement.buffered.length, 1);
                  assert_equals(mediaSource.duration, mediaElement.buffered.end(0));

                  // Play the last half second of media to verify 'ended' event is observed. The
                  // ended event should be triggered when currentTime >= duration, so ensure that
                  // earlier use of high-precision does not prevent this.
                  assert_greater_than(mediaSource.duration, .5);
                  mediaElement.currentTime = mediaSource.duration - .5;

                  test.expectEvent(mediaElement, "ended");
                  mediaElement.play();

                  test.waitForExpectedEvents(test.step_func_done());
              });
          }, "Test high precision duration is returned, then truncated upon endOfStream()");
        </script>
    </body>
</html>
